﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using WcfGeebaServer.ContentManage;

namespace WcfGeebaServer.DBDAL
{
    public class ThreadDA
    {
        public static ThreadDA GetThreadDA()
        {
            return new ThreadDA();
        }

        public List<GPost> GetPosts(GThread thread)
        {
            var query = from threadRow in Data.threads
                        where !threadRow.IsparentThreadNull() && threadRow.parentThread == thread.Id
                        select threadRow;
            
            List<GPost> result = new List<GPost>();
            foreach (var row in query)
            {
                result.Add(new GPost(row.thread_id, row.thread_subject,
                   row.thread_content, MemberDA.getMemberDA().GetMember(row.publishedBy), thread, row.publishDate, row.modifiedDate));
            }

            return result;
        }

        /// <summary>
        /// Add new thread to subforum
        /// </summary>
        /// <param name="thread">The new thread</param>
        /// <param name="subforum">The subforum, the thread will added to</param>
        /// <returns>The new thread id, -1 if fails</returns>
        public int AddThread(GThread thread, GSubForum subforum)
        {
            int affectedRows = Data.threadsAdapter.Insert(thread.Subject, thread.Content, thread.publishedBy.Username,
                DateTime.Now, DateTime.Now, null, subforum.Topic);
            Data.threads = Data.threadsAdapter.GetData();
            if (affectedRows > 0)
            {
                return Data.threads.Last().thread_id;
            }
            return -1;
        }
        
        /// <summary>
        /// Remove thread from subforum
        /// </summary>
        /// <param name="thread">The thread to remove</param>
        /// <param name="subforum">The subforum, from which remove the thread</param>
        /// <returns>true if removed. else false</returns>
        public bool RemoveThread(GThread thread, GSubForum subforum)
        {
            GeebaDS.ThreadsRow toRemove =  Data.threads.FindBythread_id(thread.Id);

            if (toRemove == null)
            {
                return false;
            }

            if (Data.threadsAdapter.Delete(toRemove.thread_id) > 0)
            {
                toRemove.Delete();
                toRemove.AcceptChanges();
                return true;
            }

            return false;
        }

        /// <summary>
        /// Add new post
        /// </summary>
        /// <param name="post">The new post</param>
        /// <param name="parent">The parent of the new post</param>
        /// <returns>The new post id</returns>
        public int AddPost(GPost post, GThread parent)
        {

            int affectedRows = Data.threadsAdapter.Insert(post.Subject, post.Content, post.publishedBy.Username,
                DateTime.Now, DateTime.Now, parent.Id, Data.threads.FindBythread_id(parent.Id).subForumTopic);
            Data.threads = Data.threadsAdapter.GetData();
            if (affectedRows > 0)
                return Data.threads.Last().thread_id;
            return -1;
        }

        /// <summary>
        /// Remove post from parent
        /// </summary>
        /// <param name="post">The post to remove</param>
        /// <param name="parent">The parent of the post to remove</param>
        /// /// <returns>true if removed. else false</returns>
        public bool RemovePost(GPost post, GThread parent)
        {
            GeebaDS.ThreadsRow toRemove = Data.threads.FindBythread_id(post.Id);

            if (toRemove == null)
            {
                return false;
            }

            if (Data.threadsAdapter.Delete(toRemove.thread_id) > 0)
            {
                toRemove.Delete();
                Data.threads.AcceptChanges();
                return true;
            }

            return false;
        }

        public bool EditThreadContent(GThread thread)
        {
            if (Data.threadsAdapter.UpdateThread(thread.Subject, thread.Content, thread.ModifiedDate, thread.Id) > 0)
            {
                Data.threads = Data.threadsAdapter.GetData();
                return true;
            }
            return false;
        }

        public GThread GetThread(int threadId, GSubForum subForum)
        {
            GeebaDS.ThreadsRow thread = Data.threads.FindBythread_id(threadId);
            if (thread == null)
                return null;

            GThread result;
            if (!thread.IsparentThreadNull())
            {
                result = new GPost(thread.thread_id, thread.thread_subject,
                    thread.thread_content, MemberDA.getMemberDA().GetMember(thread.publishedBy),
                    GetThread(thread.parentThread, subForum), thread.publishDate, thread.modifiedDate);
            }
            else
            {
                result = new GThread(thread.thread_id, thread.thread_subject,
                    thread.thread_content, MemberDA.getMemberDA().GetMember(thread.publishedBy),
                    thread.publishDate, thread.modifiedDate);
            }

            return result;
        }

        public GPost GetPost(int postId, GThread thread)
        {
            GeebaDS.ThreadsRow postRow = Data.threads.FindBythread_id(postId);

            if (postRow == null || postRow.IsparentThreadNull() || postRow.parentThread != thread.Id)
                return null;

            return new GPost(postRow.thread_id, postRow.thread_subject,
                    postRow.thread_content, MemberDA.getMemberDA().GetMember(postRow.publishedBy),
                    thread, postRow.publishDate, postRow.modifiedDate);
        }

        public List<GThread> findThreadsByContent(string content)
        {
            var query = from thread in Data.threads
                        where thread.thread_content.Contains(content)
                        select thread;

            List<GThread> result = new List<GThread>();
            foreach (var row in query)
            {
                result.Add(new GThread(row.thread_id,
                    row.thread_subject,
                    row.thread_content,
                    MemberDA.getMemberDA().GetMember(row.publishedBy),
                    row.publishDate,
                    row.modifiedDate));
            }

            return result;

        }

        public GSubForum GetSubforum(GThread thread)
        {
            var query = (from row in Data.threads
                        where row.thread_id == thread.Id
                        select row.subForumTopic).Single();

            GSubForum res = new GSubForum(query);
            return res;
        }

        public List<GThread> findThreadsByUser(string username)
        {
            var query = from thread in Data.threads
                        where thread.publishedBy == username
                        select thread;

            List<GThread> result = new List<GThread>();
            foreach (var row in query)
            {
                result.Add(new GThread(row.thread_id,
                    row.thread_subject,
                    row.thread_content,
                    MemberDA.getMemberDA().GetMember(row.publishedBy),
                    row.publishDate,
                    row.modifiedDate));
            }

            return result;
        }

        public GThread getTopicRoot(GPost post)
        {
            GThread res = post.ParentThread;
            while (res is GPost)
            {
                res = ((GPost)res).ParentThread;
            }

            return res;
        }
    }
}